package com.cps.match.connection;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.util.Map;

import org.apache.log4j.Logger;

import com.google.gdata.client.authn.oauth.OAuthException;
import com.google.gdata.client.authn.oauth.OAuthParameters;
import com.google.gdata.client.authn.oauth.OAuthRsaSha1Signer;
import com.google.gdata.client.authn.oauth.OAuthUtil;
import com.google.gdata.util.common.util.Base64;

public class ConnectionHelper {
	protected static final Logger log = Logger.getLogger(ConnectionHelper.class);
	private ConnectionHelper() {
		
	}
	public static ConnectionHelper getInstance() {
		return new ConnectionHelper();
	}
	
  

	/*
	 * Establish an OAuth connection to OpenAPI over HTTPS.
	 * 
	 * @param httpsURL The full URL to call, including any querystring
	 * parameters.
	 * 
	 * @param body The body to include. If this has a body, an HTTP POST will be
	 * established, this content will be used to generate the oauth_body_hash
	 * and the contents passed as the body of the request. If the body parameter
	 * is null, an HTTP GET will be established.
	 */
	public HttpURLConnection createOpenAPIConnection(String httpsURL, String body) throws IOException, OAuthException, NoSuchAlgorithmException {
		HttpURLConnection con = null;
		PrivateKey privKey = SecurityHolder.getPrivateKey();
		if (privKey != null) {
			
			OAuthParameters oAuthparams = SecurityHolder.getDefaultOAuthParam();

			String method = "GET";
			if (body != null) {
				method = "POST";

				MessageDigest digest = MessageDigest.getInstance("SHA-1");
				digest.reset();
				byte[] hash = digest.digest(body.getBytes("UTF-8"));
				String encodedHash = Base64.encode(hash);

				oAuthparams.addCustomBaseParameter("oauth_body_hash", encodedHash);
			}

			String baseString = OAuthUtil.getSignatureBaseString(httpsURL, method, oAuthparams.getBaseParameters());
			System.out.println(baseString);

			OAuthRsaSha1Signer rsaSigner = new OAuthRsaSha1Signer();
			rsaSigner.setPrivateKey(privKey);
			String signature = rsaSigner.getSignature(baseString, oAuthparams);

			oAuthparams.addCustomBaseParameter("oauth_signature", signature);

			URL url = new URL(httpsURL);
			con = (HttpURLConnection) url.openConnection();
			con.setRequestMethod(method);
//			con.setSSLSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault());
			con.setDoOutput(true);
			con.setDoInput(true);
			con.addRequestProperty("Authorization", buildAuthHeaderString(oAuthparams));

			System.out.println(buildAuthHeaderString(oAuthparams));

			if (body != null) {
				con.addRequestProperty("content-type", "application/xml");
				con.addRequestProperty("content-length", Integer.toString(body.length()));
			}
			con.connect();

			if (body != null) {
				OutputStreamWriter request = new OutputStreamWriter(con.getOutputStream());
				request.append(body);
				request.flush();
				request.close();
			}

		}

		return con;
	}

	private String buildAuthHeaderString(OAuthParameters params) {
		StringBuffer buffer = new StringBuffer();
		int cnt = 0;
		buffer.append("OAuth ");
		Map<String, String> paramMap = params.getBaseParameters();
		Object[] paramNames = paramMap.keySet().toArray();
		for (Object paramName : paramNames) {
			String value = paramMap.get((String) paramName);
			buffer.append(paramName + "=\"" + OAuthUtil.encode(value) + "\"");
			cnt++;
			if (paramNames.length > cnt) {
				buffer.append(",");
			}

		}
		return buffer.toString();
	}
}
